home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #1 / Ham Radio 2000.iso / ham2000 / tcp_ip / tnos / tnos100s / mailfor.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-13  |  10.4 KB  |  450 lines

  1. /* The following code will broadcast 'Mail for:' beacons
  2.  * for private users with unread mail on a regular interval
  3.  *
  4.  * Also contains the commands to set the R: header read options
  5.  * with the 'bulletin' command.
  6.  *
  7.  * original: 920306
  8.  * rewritten: 920326
  9.  * Copyright 1992, Johan. K. Reinalda, WG7J/PA3DIS
  10.  * Permission granted for non-commercial use only!
  11.  */
  12. #include <stdio.h>
  13. #include <dir.h>
  14. #include <dos.h>
  15. #include "global.h"
  16. #include "files.h"
  17. #include "dirutil.h"
  18. #include "bm.h"
  19. #include "cmdparse.h"
  20. #include "timer.h"
  21. #include "pktdrvr.h"
  22. #include "ax25.h"
  23. #include "mailfor.h"
  24.  
  25. #ifdef MAILFOR
  26. #ifdef AX25
  27.  
  28. #define MAXMFLEN 256
  29. static struct timer Mftimer;
  30. static char ax_mftext[MAXMFLEN+1] = "Mail for:";
  31. #define DEFMFLEN 9
  32. int mflen = DEFMFLEN; /*Initial lenght of mail-for string*/
  33.  
  34. struct no_mf *No_mf = NULLMF;
  35.  
  36.  
  37. /*Read a private message area's control file, searching for unread mail
  38.  *this is indicated by the status int
  39.  */
  40.  
  41. int
  42. checknewmail(area)
  43. char *area;
  44. {
  45. FILE *fp;
  46. char mailbox[100];
  47. long size;
  48. int i, nmsgs;
  49. struct    let *cmsg;
  50. struct let *new;
  51. int ret = 0;
  52.  
  53.     sprintf(mailbox,"%s/CONTROL/%s.ctl",Mailspool,area);
  54.     if((fp = fopen(mailbox,READ_BINARY)) != NULLFILE)    {
  55.         size = filelength (fileno(fp));
  56.         new = (struct let *) malloc (size);
  57.         pwait (NULL);
  58.         fread (new, size, 1, fp);
  59.         fclose(fp);
  60.         pwait (NULL);
  61.         nmsgs = (int) (size / (long) sizeof(struct let));
  62.         for (cmsg = new,i = 0; i < nmsgs; i++, cmsg++)    {
  63.             if (!(cmsg->status & BM_READ))    {
  64.                 ret = 1;
  65.                 break;
  66.                 }
  67.             }
  68.         free (new);
  69.         }
  70.     return ret;
  71. }
  72.  
  73.  
  74. /* Check name with exclude list;
  75.  * returns 1 if found, 0 if not
  76.  */
  77. int
  78. mf_exclude(name)
  79. char *name;
  80. {
  81. struct no_mf *nm;
  82.  
  83.     /*Now check the 'exclude' list*/
  84.     for(nm=No_mf;nm!=NULLMF;nm=nm->next) {
  85.         if(!stricmp(nm->area,name))
  86.             return 1;
  87.     }
  88.     return 0;
  89. }
  90.  
  91.  
  92. #ifdef CONVERS
  93. static char ActiveMessages[] = "Active Messages: %ld  (%s in conference sessions)";
  94. #else
  95. static char ActiveMessages[] = "Active Messages: %ld";
  96. #endif
  97. long ACTIVEMessages;
  98.  
  99. void
  100. countMessages()
  101. {
  102. char buf[128];
  103. struct ffblk ff;
  104. long size;
  105.  
  106.     ACTIVEMessages = 0;
  107.     sprintf(buf,"%s/CONTROL/*.ctl",Mailspool);
  108.     if (findfirst(buf, &ff, 0) == 0) {
  109.         do {
  110.             pwait(NULL);    /* Let others run */
  111.             sprintf (buf, "%s/CONTROL/%s", Mailspool, ff.ff_name);
  112.             size = fsize (buf);
  113.             ACTIVEMessages += (size / 14L);
  114.         } while (findnext(&ff) == 0);
  115.     }
  116. }
  117.  
  118.  
  119. int
  120. setmailfor()
  121. {
  122. char buf[80];
  123. struct ffblk ff;
  124.  
  125.     sprintf(buf,"%s/*.txt",Mailspool);
  126.     if (findfirst(buf, &ff, 0) == 0) {
  127.         do {
  128.             pwait(NULL);    /* Let others run */
  129.             *(strchr(ff.ff_name,'.')) = '\0';
  130.             /*must be private mail area, and not on exclude list !*/
  131.             if(!issysarea(ff.ff_name) && !mf_exclude(ff.ff_name)) {
  132.                 if((strlen(ax_mftext) + strlen(ff.ff_name)) > MAXMFLEN - 1)
  133.                     break; /* That's all folks */
  134.                 if(checknewmail(ff.ff_name)) {
  135.                     strcat(ax_mftext," ");
  136.                     strcat(ax_mftext,ff.ff_name);
  137.                 }
  138.             }
  139.            } while (findnext(&ff) == 0);
  140.     }
  141.  
  142.     countMessages();
  143.  
  144.     return strlen(ax_mftext);
  145. }
  146.  
  147.  
  148. /*This is the low-level broadcast function.*/
  149. void
  150. ax_mf(ifp)
  151. struct iface *ifp;
  152. {
  153. struct mbuf *bp;
  154. int inconference = 0;
  155. char fakestr[8];
  156.  
  157.     /* prepare the header */
  158.     if((bp = alloc_mbuf(mflen)) == NULLBUF)
  159.         return;
  160.  
  161.     /*copy the data into the packet*/
  162.     bp->cnt = mflen;
  163.     memcpy(bp->data,ax_mftext,mflen);
  164.  
  165.     /* send it */
  166.     (*ifp->output)(ifp, Ax25multi[MAILCALL], ifp->hwaddr,
  167.         PID_NO_L3, bp);
  168.  
  169.  
  170.     /* prepare the header */
  171.     if((bp = alloc_mbuf(strlen(ActiveMessages)+16)) == NULLBUF)
  172.         return;
  173.  
  174.     /*copy the data into the packet*/
  175. #ifdef CONVERS
  176.     inconference = CountConfUsers();
  177.     sprintf(bp->data,ActiveMessages, ACTIVEMessages, (inconference) ? itoa(inconference, fakestr, 10) : "NONE");
  178. #else
  179.     sprintf(bp->data,ActiveMessages, ACTIVEMessages);
  180. #endif
  181.     bp->cnt = strlen (bp->data);
  182.  
  183.     /* send it */
  184.     (*ifp->output)(ifp, Ax25multi[MAILCALL], ifp->hwaddr,
  185.         PID_NO_L3, bp);
  186. }
  187.  
  188.  
  189. void
  190. Mftick(v)
  191. void *v;
  192. {
  193. struct iface *ifp = Ifaces;
  194.  
  195.     stop_timer(&Mftimer); /* in case this was 'kicked' with a 'mailfor now'*/
  196.  
  197.     /*Now find private mail areas with unread mail.
  198.      *add these to the info-line
  199.      */
  200.     ax_mftext[DEFMFLEN] = '\0'; /* Back to only 'Mail for:' again*/
  201.     if((mflen=setmailfor()) < DEFMFLEN+1) {
  202.         start_timer(&Mftimer);
  203.         return; /* No unread mail */
  204.     }
  205.  
  206.     /*broadcast it on all configured interfaces*/
  207.     for(ifp=Ifaces;ifp != NULL;ifp=ifp->next)
  208.         if(ifp->flags & MAIL_BEACON)
  209.             ax_mf(ifp);
  210.     /* Restart timer */
  211.     start_timer(&Mftimer) ;
  212. }
  213.  
  214.  
  215. int
  216. dombmailfor(argc,argv,p)
  217. int argc;
  218. char *argv[];
  219. void *p;
  220. {
  221. register int i;
  222. struct no_mf *nm;
  223. int inconference = 0;
  224. char fakestr[8];
  225.  
  226.     if(argc < 2)    {    /* set the timer */
  227.             tprintf("Mail-for timer: %lu/%lu\n",
  228.             read_timer(&Mftimer)/1000L,
  229.             dur_timer(&Mftimer)/1000L);
  230.         if(ACTIVEMessages)    {
  231. #ifdef CONVERS
  232.             inconference = CountConfUsers();
  233.             tprintf(ActiveMessages, ACTIVEMessages, (inconference) ? itoa(inconference, fakestr, 10) : "NONE");
  234. #else
  235.             tprintf(ActiveMessages, ACTIVEMessages);
  236. #endif
  237.             tputs ("\n");
  238.         }
  239.             if(mflen > DEFMFLEN)
  240.             tprintf("%s\n",ax_mftext);
  241.         tputs ("\n");
  242.             return 0;
  243.         }
  244.     if(*argv[1] == 'n')     { /*send mailfor 'now' !!*/
  245.             Mftick(NULL);
  246.             return 0;
  247.         }
  248.     if(*argv[1] == 'e')     { /*exclude list */
  249.             /*the exclude subcommand*/
  250.             if(argc == 2) { /*just list them*/
  251.             for(nm=No_mf;nm!=NULLMF;nm=nm->next)
  252.                         tprintf("%s ",nm->area);
  253.             tputc('\n');
  254.         } else { /*add some call(s)*/
  255.             for(i=0;i<argc-2;i++) {
  256.                         if(strlen(argv[i+2]) > 8) {
  257.                             tprintf("Invalid: %s\n",argv[i+2]);
  258.                     continue;
  259.                             }
  260.                 nm = callocw(1,sizeof(struct no_mf));
  261.                         strcpy(nm->area,argv[i+2]);
  262.                         /* add to list */
  263.                         nm->next = No_mf;
  264.                         No_mf = nm;
  265.                         }
  266.                 }
  267.             return 0;
  268.             }
  269.     Mftimer.func = (void (*)())Mftick;/* what to call on timeout */
  270.     Mftimer.arg = NULL;        /* dummy value */
  271.     set_timer(&Mftimer,atol(argv[1])*1000L); /* set timer duration */
  272.     Mftick(NULL); /* Do one now and start it all!*/
  273.     return 0;
  274. }
  275. #endif /* AX25 */
  276. #endif /* MAILFOR */
  277.  
  278. /*************************************************************************/
  279.  
  280. #ifdef RLINE
  281.  
  282. /* Depending on the flag set, the mailbox will
  283.  * read the message's original date,
  284.  * the correct 'from' address (instead of the user%forwardbbs@myhost),
  285.  * and for buls set the X-Forwarded options to prevent
  286.  * unneccesary forward attempts
  287.  * all from the R: lines supplied by the bbs system
  288.  * 920311 - WG7J
  289.  */
  290. static int dordate __ARGS((int argc,char *argv[],void *p));
  291. static int dorreturn __ARGS((int argc,char *argv[],void *p));
  292. static int dombloophold __ARGS((int argc,char *argv[],void *p));
  293. static int dofwdcheck __ARGS((int argc,char *argv[],void *p));
  294. static int dombhold __ARGS((int argc,char *argv[],void *p));
  295.  
  296. char MyFwds[NUMFWDBBS][FWDBBSLEN+1];
  297. int Numfwds = 0;
  298. int Checklock = 0;   /* get increased to lock list of forward bbses */
  299. int Rdate = 0;
  300. int Rreturn = 0;
  301. int Rfwdcheck = 0;
  302.  
  303. static struct cmds Rlinetab[] = {
  304.     "check",    dofwdcheck,0, 0, NULLCHAR,
  305.     "date",     dordate,   0, 0, NULLCHAR,
  306.     "hold",     dombhold,  0, 0, NULLCHAR,
  307.     "loophold", dombloophold,0,0, NULLCHAR,
  308.     "return",   dorreturn, 0, 0, NULLCHAR,
  309.     NULLCHAR,
  310. };
  311.  
  312. void ReadFwdBbs();
  313.  
  314. static int
  315. dordate(argc,argv,p)
  316. int argc;
  317. char *argv[];
  318. void *p;
  319. {
  320.     return setbool(&Rdate,"Use R: for orig. date",argc,argv);
  321. }
  322.  
  323. int Mbloophold = 2;
  324.  
  325. /* set loop detection threshold - WG7J */
  326. static int
  327. dombloophold(argc, argv,p)
  328. int argc;
  329. char *argv[];
  330. void *p;
  331. {
  332.     return setint(&Mbloophold,"Loop hold after",argc,argv);
  333. }
  334.  
  335. static int
  336. dorreturn(argc,argv,p)
  337. int argc;
  338. char *argv[];
  339. void *p;
  340. {
  341.     return setbool(&Rreturn,"Use R: for ret. addr.",argc,argv);
  342. }
  343.  
  344.  
  345. static int
  346. dofwdcheck(argc,argv,p)
  347. int argc;
  348. char *argv[];
  349. void *p;
  350. {
  351.     register int i;
  352.  
  353.     setbool(&Rfwdcheck,"Use R: to check buls",argc,argv);
  354.     if((argc == 1) && Rfwdcheck && Numfwds) { /*list the bbses we check*/
  355.         tputs("Checking for:");
  356.         for(i=0;i<Numfwds;i++)
  357.             tprintf(" %s",MyFwds[i]);
  358.         tputc('\n');
  359.     } else {
  360.         if(Rfwdcheck)
  361.             ReadFwdBbs();
  362.     }
  363.     return 0;
  364. }
  365.  
  366.  
  367.  
  368.  
  369. static int
  370. dombhold(argc,argv,p)
  371. int argc;
  372. char *argv[];
  373. void *p;
  374. {
  375.     return setbool(&MbHolding,"Hold local bulletins for review",argc,argv);
  376. }
  377.  
  378. int
  379. dombrline(argc,argv,p)
  380. int argc;
  381. char *argv[];
  382. void *p;
  383. {
  384.     return subcmd(Rlinetab,argc,argv,p);
  385. }
  386.  
  387.  
  388. void
  389. ReadFwdBbs() {
  390.     FILE *fp;
  391.     int start = 1;
  392.     char *cp;
  393.     char line[80];
  394.  
  395.     if(Checklock) {
  396.         tputs("Bbs-list locked, forward.bbs not re-read\n");
  397.         return;
  398.     }
  399.     Numfwds = 0;    /* reset */
  400.     if((fp=fopen(Forwardfile,READ_TEXT)) == NULLFILE) {
  401.         tputs("forward.bbs not found\n");
  402.         return;
  403.     }
  404.     /*Now scan the forward.bbs file to find bbs's*/
  405.     while(fgets(line,sizeof(line),fp) != NULLCHAR && (Numfwds < NUMFWDBBS)) {
  406.         if(*line == '\n')
  407.             continue;
  408.         if(*line == '#')
  409.             continue;
  410.         if((*line == '.') || (*line == '+') || (*line == '@'))
  411.             continue;
  412.         /* lines starting with '-' separate the forwarding records */
  413.         if(*line == '-') {
  414.             start = 1;
  415.             continue;
  416.         }
  417.         if(start) {
  418.             start = 0;
  419.             /* get the name of this forwarding record */
  420.             if((cp=strpbrk(line," \n\t")) != NULLCHAR)
  421.                 *cp = '\0';
  422.             if(strlen(line) > FWDBBSLEN)
  423.                 continue;   /*What kind of bbs-call is this ?*/
  424.             strcpy(MyFwds[Numfwds++],strupr(line));
  425.         }
  426.     }
  427.     fclose(fp);
  428.     return;
  429. }
  430.  
  431. #endif /* RLINE */
  432.  
  433.  
  434. int
  435. BBSlookup (bbs)
  436. char *bbs;
  437. {
  438. int retval;
  439.  
  440.     for (retval = 0; retval < Numfwds; retval++)
  441.         if (!stricmp (MyFwds[retval], bbs))
  442.             break;
  443.     if (retval == Numfwds)
  444.         return -1;
  445.     else
  446.         return retval;
  447. }
  448.  
  449.  
  450.